package com.meiqia.system.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.meiqia.common.constant.Constants;
import com.meiqia.system.entity.Content;
import com.meiqia.system.mapper.ContentMapper;
import com.meiqia.system.service.ContentService;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;


/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lightman
 * @since 2020-12-09
 */
@Service
public class ContentServiceImpl extends ServiceImpl<ContentMapper, Content> implements ContentService {

    @Autowired
    private CacheManager cacheManager;

    // 注入redis 模板对象
    @Resource
    private RedisTemplate redisTemplate;

//    @Override
//    public PageResult<Content> page(Integer currPage, Integer pageSize, SearchVO vo) {
//        // 分页
//        Page<Content> contentPage = new Page<>(currPage, pageSize);
//
//        // 条件查询
//        QueryWrapper<Content> wrapper = new QueryWrapper<>();
//
//        if (Objects.nonNull(vo)) {
//            String keyWord = vo.getKeyWord();
//            if (StringUtils.isNotEmpty(keyWord)) {
//                wrapper.like("name", keyWord);
//            }
//        }
//        contentPage = page(contentPage, wrapper);
//        return PageResult.of(contentPage.getRecords(), contentPage.getTotal());
//    }
//
//    @Override
//    public boolean saveContent(Content content) {
//        return save(content);
//    }
//
//    @Override
//    public boolean updateContent(Content content) {
//        return updateById(content);
//    }
//
//    @Override
//    public boolean delById(Long id) {
//        return removeById(id);
//    }
//
//    @Override
//    public boolean delByIds(List<Long> ids) {
//        return removeByIds(ids);
//    }

    @Override
    public List<Content> gertContentList() {

        // JVM内存区
        Cache cache = this.cacheManager.getCache("contentList");
        // 根据键获取元素
        Element element = cache.get(Constants.System.KEY_CONTENTS);

        List<Content> result = null;

        if (element != null) {
            // 解析数据
            result = (List<Content>) element.getObjectValue();
            if (CollectionUtils.isEmpty(result)) {

                return result;
            }
        }

        // 绑定对应的键
        BoundListOperations ops = redisTemplate.boundListOps(Constants.System.KEY_CONTENTS);
        // 拿到所有的数据
        result = ops.range(0, -1);
        // 如果有数据
        if (CollectionUtils.isNotEmpty(result) && result.size() > 0) {
            // redis中有数据, 假如走这一步,代表cache中没数据,我们要给cache中存数据
            cache.put(new Element(Constants.System.KEY_CONTENTS, result));
            return result;
        }


        synchronized (this) {

            // 第二次无需访问数据库
            element = cache.get(Constants.System.KEY_CONTENTS);
            if (element != null) {
                result = (List<Content>) element.getObjectValue();
                if(CollectionUtils.isNotEmpty(result)){
                    return result;
                }
            }

            result = ops.range(0, -1);

            if(CollectionUtils.isNotEmpty(result)){
                cache.put(new Element(Constants.System.KEY_CONTENTS, result));
                return result;
            }

            // 如果没数据  创建条件构造器
            LambdaQueryWrapper<Content> lambda = new QueryWrapper<Content>().lambda();
            lambda.eq(Content::getStatus, 1).orderByDesc(Content::getSort);
            // 拿到所有要展示的数据
            result = list(lambda);

            if (!CollectionUtils.isEmpty(result)) {
//            // 放入ehache
                cache.put(new Element(Constants.System.KEY_CONTENTS, result));
                // 存redis 转化为数据,因为底层就会少一个数组
                ops.leftPushAll(result.toArray());
            }else {

            }
        }


        return result;
    }
}
